package com.ysqcould.mp.utils;

import com.ysqcould.common.enums.WxResultStatus;
import com.ysqcould.common.exception.WxApiException;
import com.ysqcould.mp.domain.vo.WxResultBody;
import org.apache.commons.lang3.StringUtils;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import static com.ysqcould.common.enums.MpBaseResp.FREQ_CONTROL;
import static com.ysqcould.common.enums.MpBaseResp.INVALID_SESSION;

/**
 * 微信登录二维码生成工具类
 */
public class QrCodeUtil {
    /**接口地址**/
    public static final Map<String, String> URL_MAP = new HashMap<>();

    static {
        //初始化登录cookie
        URL_MAP.put("startLogin", "https://mp.weixin.qq.com/cgi-bin/bizlogin?action=startlogin");

        //二维码图片接口
        URL_MAP.put("getqrcode", "https://mp.weixin.qq.com/cgi-bin/ ");

        //二维码扫描状态接口
        URL_MAP.put("qrcodeAsk", "https://mp.weixin.qq.com/cgi-bin/scanloginqrcode");

        //扫码确认后，登录接口
        URL_MAP.put("bizlogin", "https://mp.weixin.qq.com/cgi-bin/bizlogin?action=login");
    }

    /**
     * 微信请求登录
     * @param sessionid
     * @return
     */
   public static WxResultBody startLogin(String sessionid){
       if (StringUtils.isBlank(sessionid)) {
           sessionid = "" + System.currentTimeMillis() + (int)(Math.random()*100);
       }

       Map<String, String> params = new HashMap<>(8);
       params.put("sessionid", sessionid);
       params.put("userlang", "zh_CN");
       params.put("redirect_url", "");
       params.put("login_type", "3");
       params.put("token", "");
       params.put("lang", "zh_CN");
       params.put("f", "json");
       params.put("ajax", "1");

       WxResultBody wxResultBody = parseWxResultBody(HttpUtils.doPost(URL_MAP.get("startLogin"), params));

       return wxResultBody;
   }

    /**
     * 获取二维码图片 字节输出流
     * @return
     */
    public static InputStream getQRCode() {
        Map<String, String> params = new HashMap<>(2);
        params.put("action", "getqrcode");
        params.put("random", System.currentTimeMillis() + "");
        InputStream inputStream = HttpUtils.doGetStream(URL_MAP.get("getqrcode"), params);

        return inputStream;
    }

    /**
     * GET 轮询二维码状态接口
     * @return
     */
    public static WxResultBody askQRCode() {
        Map<String, String> params = new HashMap<>(5);
        params.put("action", "ask");
        params.put("token", "");
        params.put("lang", "zh_CN");
        params.put("f", "json");
        params.put("ajax", "1");

        WxResultBody wxResultBody = parseWxResultBody(HttpUtils.doGet(URL_MAP.get("qrcodeAsk"), params));

        return wxResultBody;
    }

    /**
     * 扫码确认后，登录接口
     * @return
     */
    public static WxResultBody bizlogin() {
        Map<String, String> params = new HashMap<>(10);
        params.put("userlang", "zh_CN");
        params.put("redirect_url", "");
        params.put("cookie_forbidden", "0");
        params.put("cookie_cleaned", "0");
        params.put("plugin_used", "0");
        params.put("login_type", "3");
        params.put("token", "");
        params.put("lang", "zh_CN");
        params.put("f", "json");
        params.put("ajax", "1");

        WxResultBody wxResultBody = parseWxResultBody(HttpUtils.doPost(URL_MAP.get("bizlogin"), params));

        return wxResultBody;
    }

    /**
     * 扫码确认后，登录接口
     * @return
     */
    public static String updateToken() {
        Map<String, String> params = new HashMap<>(10);
        params.put("userlang", "zh_CN");
        params.put("redirect_url", "");
        params.put("cookie_forbidden", "0");
        params.put("cookie_cleaned", "0");
        params.put("plugin_used", "0");
        params.put("login_type", "3");
        params.put("token", "");
        params.put("lang", "zh_CN");
        params.put("f", "json");
        params.put("ajax", "1");

        final String bizlogin = HttpUtils.doPost(URL_MAP.get("bizlogin"), params);

        return bizlogin;
    }
    /**
     * 转成java bean
     * @param jsonRes json结果字符串
     * @return
     */
    public static WxResultBody parseWxResultBody(String jsonRes) {
        WxResultBody wxResultBody = JsonUtils.jsonToObj(jsonRes, WxResultBody.class);

        checkIsSuccess(wxResultBody);

        return wxResultBody;
    }

    /**
     * 判断请求是否成功
     * @param wxResultBody
     */
    public static void checkIsSuccess(WxResultBody wxResultBody) {
        // 判断是否请求成功
        if (wxResultBody == null) {
            throw new WxApiException(WxResultStatus.FAIL_NULL_RES);
        }

        if (wxResultBody.getBase_resp().getRet() == null
                || wxResultBody.getBase_resp().getRet() != 0) {
            // 需重新扫码登录
            if (wxResultBody.getBase_resp().getRet() == INVALID_SESSION.getRet()) {
                throw new RuntimeException("操作失败：" + INVALID_SESSION.getErrMsg());
            }
            // 频率控制
            if (wxResultBody.getBase_resp().getRet() == FREQ_CONTROL.getRet()) {
                throw new RuntimeException("操作失败：" + FREQ_CONTROL.getErrMsg());
            }
            throw new WxApiException(WxResultStatus.FAIL_STATUS);
        }
    }
}
